define(['jquery', 'knockout', 'dataservice', 'eventbus', 'util', 'jcloud'], function ($, ko, ds, eventbus, util, jc) {
	return function () {
		// List of words.
		let words = ko.observable({});
		// Search term from the user.
		let wordsUserInput = ko.observable(""); //FROM USER
		// List of words prepared for visualization;
		let wordsToVisualize = ko.observable([]);
		// The canvas on which to draw the word cloud.
		let canvas = ko.observable("");
		// Dimensions of the canvas.
		let width = 500;
		let height = 300;
		// The error message.
		let errorStatus = ko.observable("Please enter something and search");

		// Initialization of the canvas.
		// TODO: think of a smarter way to deal with this in a more knockout way.
		canvas($("#canvas").jQCloud(
			wordsToVisualize(),
			{
				width,
				height
			}
		).html());

		// Retrieves the WW and updates the word cloud or the error message.
		let retrieveWeightedWords = function (data) {
			if (data.words.length === 0) errorStatus("No results");
			else errorStatus("");
			wordsToVisualize(data.words.map(function (word) {
				// Converts each element to the jQcloud format.
				return { "text": word.word, "weight": word.frequency };
			}));
			updateWordCloud();
		};

		// Updates the word cloud. TODO: finish this up.
		let updateWordCloud = function () {
			canvas($("#canvas").jQCloud("update",
				wordsToVisualize()
			).html());
		}

		// Submit callback for doing a WW search.
		let submit = function () {
			if (this.wordsUserInput() !== "") ds.getWeightedWords(retrieveWeightedWords, this.wordsUserInput());
			else {
				errorStatus("Please enter something and search");
				wordsToVisualize({});
				updateWordCloud();
			}
		}

		// Retrieves words with a provided url.
		let getWords = function (url) {
			ds.getWeightedWords(retrieveSearches, url);
		}

		// Expose the needed properties for the UI.
		return {
			title: 'Word Clouds',
			words,
			wordsUserInput,
			wordsToVisualize,
			updateWordCloud,
			submit,
			getWords,
			canvas,
			errorStatus,
		}
	}
});